﻿// See https://aka.ms/new-console-template for more information
using Confluent.Kafka;
using CSRedis;
using Newtonsoft.Json;
using QskjLibrary;
using QskjServiceVehicleAlramToKafka.Dto;
using System.Data;
using System.Globalization;
using System.Security.Cryptography;
using System.Text;

Console.WriteLine("Hello, World!");
#region 消费数据 
Task.Factory.StartNew(() =>
{
    string brokerList = "192.168.3.52:9092,192.168.3.146:9092,192.168.3.164:9092";
    List<string> topics = new List<string>();
    topics.Add("VEHICLE_ALARM_FILE");
    Console.WriteLine(DateTime.Now.ToString() + "qskj设备告警证据数据kafka消费开始");

    try
    {
        Consumer(brokerList, topics);
    }
    catch (Exception e)
    {
        Console.WriteLine("qskj设备告警证据数据kafka消费异常" + e);
    }
    while (true)
    {
        Thread.Sleep(1000 * 200);
    }
});
Task.Factory.StartNew(() =>
{
    string brokerList = "192.168.3.52:9092,192.168.3.146:9092,192.168.3.164:9092";
    List<string> topics = new List<string>();
    topics.Add("VEHICLE_ALARM");
    Console.WriteLine(DateTime.Now.ToString() + "qskj设备告警数据kafka消费开始");

    try
    {
        Consumer(brokerList, topics);
    }
    catch (Exception e)
    {
        Console.WriteLine("qskj设备告警数据kafka消费异常" + e);
    }
    while (true)
    {
        Thread.Sleep(1000 * 200);
    }
});
Task.Factory.StartNew(() =>
{
    string brokerList = "192.168.3.52:9092,192.168.3.146:9092,192.168.3.164:9092";
    List<string> topics = new List<string>();
    topics.Add("topic-media-complete");
    Console.WriteLine(DateTime.Now.ToString() + "qskj设备告警数据kafka消费开始");

    try
    {
        Consumer(brokerList, topics);
    }
    catch (Exception e)
    {
        Console.WriteLine("qskj设备告警数据kafka消费异常" + e);
    }
    while (true)
    {
        Thread.Sleep(1000 * 200);
    }
});
#endregion

while (true)
{
    Thread.Sleep(5000);
}
async void Producer(string brokerList, string topicName, string text)
{
    //Console.WriteLine(topicName + "数据生产");
    var config = new ProducerConfig { BootstrapServers = brokerList };

    using (var producer = new ProducerBuilder<string, string>(config).Build())
    {
        //Console.WriteLine($"Producer {producer.Name} producing on topic {topicName}.");

        {
            string key = Guid.NewGuid().ToString();
            string val = text;
            try
            {
                // Note: Awaiting the asynchronous produce request below prevents flow of execution
                // from proceeding until the acknowledgement from the broker is received (at the 
                // expense of low throughput).
                var deliveryReport = await producer.ProduceAsync(
                    topicName, new Message<string, string> { Key = key, Value = val });

                //Console.WriteLine($"delivered to: {deliveryReport.TopicPartitionOffset}");
            }
            catch (ProduceException<string, string> e)
            {
                Console.WriteLine($"failed to deliver message: {e.Message} [{e.Error.Code}] Topic:{topicName}---生产数据失败");
            }
        }

    }
}
async void Consumer(string brokerList, List<string> topics)
{
    CancellationTokenSource cts = new CancellationTokenSource();
    Console.CancelKeyPress += (_, e) =>
    {
        e.Cancel = true; // prevent the process from terminating.
        cts.Cancel();
    };
    Run_Consume(brokerList, topics, cts.Token);
}
/// <summary>
///     In this example
///         - offsets are automatically committed.
///         - no extra thread is created for the Poll (Consume) loop.
/// </summary>
void Run_Consume(string brokerList, List<string> topics, CancellationToken cancellationToken)
{
    CSRedisClient redisDb = null;
    if (redisDb == null)
    {
        redisDb = RedisHelp.GetInstance();
    }
    CSRedisClient redisDb3 = null;
    if (redisDb3 == null)
    {
        redisDb3 = RedisHelp.GetInstance3();
    }
    //string brokerList = "192.168.3.52:9092,192.168.3.146:9092,192.168.3.164:9092";
    var config = new ConsumerConfig
    {
        BootstrapServers = brokerList,
        GroupId = "ALARM_File_FromRedisToKafka",
        EnableAutoOffsetStore = false,
        EnableAutoCommit = true,
        StatisticsIntervalMs = 5000,
        SessionTimeoutMs = 6000,
        AutoOffsetReset = AutoOffsetReset.Latest,
        EnablePartitionEof = true,
        // A good introduction to the CooperativeSticky assignor and incremental rebalancing:
        // https://www.confluent.io/blog/cooperative-rebalancing-in-kafka-streams-consumer-ksqldb/
        PartitionAssignmentStrategy = PartitionAssignmentStrategy.CooperativeSticky
    };

    // Note: If a key or value deserializer is not set (as is the case below), the 
    // deserializer corresponding to the appropriate type from Confluent.Kafka.Deserializers
    // will be used automatically (where available). The default deserializer for string
    // is UTF8. The default deserializer for Ignore returns null for all input data
    // (including non-null data).
    using (var consumer = new ConsumerBuilder<Ignore, string>(config)
        // Note: All handlers are called on the main .Consume thread.
        .SetErrorHandler((_, e) => Console.WriteLine($"Error: {e.Reason}"))
        .SetStatisticsHandler((_, json) =>
            //Console.WriteLine($"Statistics: {json}")
            Console.WriteLine("k-r-k")
            )
        .SetPartitionsAssignedHandler((c, partitions) =>
        {
            // Since a cooperative assignor (CooperativeSticky) has been configured, the
            // partition assignment is incremental (adds partitions to any existing assignment).
            //Console.WriteLine(
            //    "Partitions incrementally assigned: [" +
            //    string.Join(',', partitions.Select(p => p.Partition.Value)) +
            //    "], all: [" +
            //    string.Join(',', c.Assignment.Concat(partitions).Select(p => p.Partition.Value)) +
            //    "]");

            // Possibly manually specify start offsets by returning a list of topic/partition/offsets
            // to assign to, e.g.:
            // return partitions.Select(tp => new TopicPartitionOffset(tp, externalOffsets[tp]));
        })
        .SetPartitionsRevokedHandler((c, partitions) =>
        {
            // Since a cooperative assignor (CooperativeSticky) has been configured, the revoked
            // assignment is incremental (may remove only some partitions of the current assignment).
            var remaining = c.Assignment.Where(atp => partitions.Where(rtp => rtp.TopicPartition == atp).Count() == 0);
            //Console.WriteLine(
            //    "Partitions incrementally revoked: [" +
            //    string.Join(',', partitions.Select(p => p.Partition.Value)) +
            //    "], remaining: [" +
            //    string.Join(',', remaining.Select(p => p.Partition.Value)) +
            //    "]");
        })
        .SetPartitionsLostHandler((c, partitions) =>
        {
            // The lost partitions handler is called when the consumer detects that it has lost ownership
            // of its assignment (fallen out of the group).
            //Console.WriteLine($"Partitions were lost: [{string.Join(", ", partitions)}]");
        })
        .Build())
    {
        consumer.Subscribe(topics);

        try
        {
            while (true)
            {
                try
                {
                    var consumeResult = consumer.Consume(cancellationToken);

                    if (consumeResult.IsPartitionEOF)
                    {
                        //Console.WriteLine(
                        //    $"Reached end of topic {consumeResult.Topic}, partition {consumeResult.Partition}, offset {consumeResult.Offset}.");

                        continue;
                    }

                    //Console.WriteLine($"Received message at {consumeResult.TopicPartitionOffset}: {consumeResult.Message.Value}");
                    if (consumeResult.Topic == "VEHICLE_ALARM_FILE")
                    {
                        try
                        {
                            VehicleAlarm vehicle = new VehicleAlarm(); vehicle = JsonConvert.DeserializeObject<VehicleAlarm>(consumeResult.Message.Value);
                            if (string.IsNullOrWhiteSpace(vehicle.latitude))
                            {
                                vehicle.latitude = "0";
                            }
                            if (string.IsNullOrWhiteSpace(vehicle.longitude))
                            {
                                vehicle.longitude = "0";
                            }
                            if (string.IsNullOrWhiteSpace(vehicle.speed))
                            {
                                vehicle.speed = "0";
                            }
                            if ((vehicle.alarmType == "17" || vehicle.alarmType == "34" || vehicle.alarmType == "44") && vehicle.platform == "RUIMING")
                            {
                                continue;//锐明报警证据超速不作处理
                            }
                            if ((vehicle.alarmType == "39") && vehicle.platform == "ZAKJ")
                            {
                                continue;//中安大巴报警证据超速不作处理
                            }
                            VehicleAlarmFILEDataFromRedisToKafka(vehicle, redisDb3, consumeResult.Message.Value, brokerList, redisDb);
                        }
                        catch (Exception e)
                        {
                            Console.WriteLine("数据转换失败" + consumeResult.Message.Value + "-------" + e.Message);
                        }
                    }
                    else if (consumeResult.Topic == "VEHICLE_ALARM")
                    {
                        try
                        {
                            VehicleAlarm vehicle = new VehicleAlarm(); vehicle = JsonConvert.DeserializeObject<VehicleAlarm>(consumeResult.Message.Value);
                            if (!string.IsNullOrWhiteSpace(vehicle.url))
                            {
                                if (string.IsNullOrWhiteSpace(vehicle.latitude))
                                {
                                    vehicle.latitude = "0";
                                }
                                if (string.IsNullOrWhiteSpace(vehicle.longitude))
                                {
                                    vehicle.longitude = "0";
                                }
                                if (string.IsNullOrWhiteSpace(vehicle.speed))
                                {
                                    vehicle.speed = "0";
                                }
                                VehicleAlarmFILEDataFromRedisToKafka(vehicle, redisDb3, consumeResult.Message.Value, brokerList, redisDb);
                            }
                            if ((vehicle.alarmType == "17" || vehicle.alarmType == "34" || vehicle.alarmType == "44") && vehicle.platform == "RUIMING")
                            {
                                VehicleAlarmFILEDataFromRedisToKafka(vehicle, redisDb3, consumeResult.Message.Value, brokerList, redisDb);//锐明超速报警处理
                            }
                            if ((vehicle.alarmType == "39") && vehicle.platform == "ZAKJ")
                            {
                                VehicleAlarmFILEDataFromRedisToKafka(vehicle, redisDb3, consumeResult.Message.Value, brokerList, redisDb);//中安超速报警处理
                            }
                        }
                        catch (Exception e)
                        {
                            Console.WriteLine("数据转换失败" + consumeResult.Message.Value + "-------" + e.Message);
                        }
                    }
                    else if (consumeResult.Topic == "topic-media-complete")
                    {
                        try
                        {
                            VehicleAlarmZl vehicleZl = new VehicleAlarmZl(); vehicleZl = JsonConvert.DeserializeObject<VehicleAlarmZl>(consumeResult.Message.Value);
                            VehicleAlarm vehicle = new VehicleAlarm();
                            vehicle.latitude = vehicleZl.latitude;
                            vehicle.longitude = vehicleZl.longitude;
                            vehicle.speed = vehicleZl.speed;
                            if (string.IsNullOrWhiteSpace(vehicle.latitude))
                            {
                                vehicle.latitude = "0";
                            }
                            if (string.IsNullOrWhiteSpace(vehicle.longitude))
                            {
                                vehicle.longitude = "0";
                            }
                            if (string.IsNullOrWhiteSpace(vehicle.speed))
                            {
                                vehicle.speed = "0";
                            }
                            {
                                byte[] result = Encoding.Default.GetBytes(vehicleZl.AlarmID);//报警号过长使用MD5摘要处理
                                MD5 md5 = new MD5CryptoServiceProvider();
                                byte[] output = md5.ComputeHash(result);
                                vehicle.alarmId = BitConverter.ToString(output).Replace("-", "");
                                //Console.WriteLine(vehicle.alarmId);
                            }
                            if (string.IsNullOrWhiteSpace(vehicleZl.AttachPath))
                            {
                                continue;
                            }
                            vehicle.url = vehicleZl.AttachPath;
                            string[] str = vehicleZl.RelativePath.Split('/');
                            string zlTerKey = redisDb.Get("zl_" + str[1]);
                            if (!string.IsNullOrEmpty(zlTerKey))
                            {
                                vehicle.vehicleNo = zlTerKey;
                            }
                            else
                            {
                                string sql = $@"select license_plate from qskj.B_Taxi where  zlterminalkey='{str[1]}'";
                                object o = MySqlHelper.ExecuteScalar(CommandType.Text, sql);
                                vehicle.vehicleNo = o == null || o == DBNull.Value ? "xxx" : o.ToString();
                                if (!string.IsNullOrEmpty(vehicle.vehicleNo))
                                {
                                    redisDb.Set("zl_" + str[1], vehicle?.vehicleNo);
                                    redisDb.Set("zl_" + vehicle?.vehicleNo, str[1]);
                                }
                            }
                            if (vehicle.vehicleNo != "xxx" && !string.IsNullOrWhiteSpace(vehicle.vehicleNo))
                            {
                                vehicleZl.VehicleNo = vehicle.vehicleNo;//车牌号   
                                string[] alarmInfo = str[2].Split('_');
                                string dateString = alarmInfo[4];// "20240620173040";
                                string format = "yyyyMMddHHmmss";
                                DateTime dateTime = DateTime.ParseExact(dateString, format, CultureInfo.InvariantCulture);
                                vehicle.alarmTime = dateTime.ToString("yyyy-MM-dd HH:mm:ss");
                                vehicle.alarmType = Convert.ToString(alarmInfo[2]);
                                vehicle.devGbId = vehicle?.vehicleNo;
                                vehicle.platform = "zl";
                                if (!string.IsNullOrWhiteSpace(vehicle.url))
                                {
                                    VehicleAlarmFILEDataFromRedisToKafka(vehicle, redisDb3, JsonConvert.SerializeObject(vehicle), brokerList, redisDb);
                                }
                            }
                        }
                        catch (Exception e)
                        {
                            Console.WriteLine("topic-media-complete数据处理到文件数据表失败" + consumeResult.Message.Value + "-------" + e.Message);
                            Console.WriteLine("异常信息：" + JsonConvert.SerializeObject(e));
                        }
                    }
                    else
                    {

                    }
                    try
                    {
                        // Store the offset associated with consumeResult to a local cache. Stored offsets are committed to Kafka by a background thread every AutoCommitIntervalMs. 
                        // The offset stored is actually the offset of the consumeResult + 1 since by convention, committed offsets specify the next message to consume. 
                        // If EnableAutoOffsetStore had been set to the default value true, the .NET client would automatically store offsets immediately prior to delivering messages to the application. 
                        // Explicitly storing offsets after processing gives at-least once semantics, the default behavior does not.
                        consumer.StoreOffset(consumeResult);
                    }
                    catch (KafkaException e)
                    {
                        Console.WriteLine($"Store Offset error: {e.Error.Reason}");
                    }
                }
                catch (ConsumeException e)
                {
                    Console.WriteLine($"Consume error: {e.Error.Reason}");
                }
            }
        }
        catch (OperationCanceledException)
        {
            Console.WriteLine("Closing consumer.");
            consumer.Close();
        }
    }
}

void VehicleAlarmFILEDataFromRedisToKafka(VehicleAlarm status, CSRedisClient redisDb3, string alarmFile, string brokerList, CSRedisClient redisDb)
{
    try
    {
        var sec = JsonConvert.DeserializeObject<VehicleAlarm>(alarmFile);
        string alarmInfo = redisDb3.Get(status.alarmId);
        if (string.IsNullOrWhiteSpace(alarmInfo))//缓存里没有报警信息则该报警号第一次进入系统
        {
            string msg = alarmFile;
            redisDb3.Set(status.alarmId, msg, new TimeSpan(12, 0, 30));
            redisDb3.Set("alarm" + status.vehicleNo, msg);//车辆报警数据刷新
            if (!string.IsNullOrWhiteSpace(status.alarmTime))//报警时间不为空才处理到数据库
            {
                Producer(brokerList, "VEHICLE_ALARMAndUrlMsg", msg);//车载设备告警数据 
                VehicleAlarmDataToMysql(status, redisDb3, redisDb);
            }
        }
        else
        {
            VehicleAlarm va = new VehicleAlarm();
            va = JsonConvert.DeserializeObject<VehicleAlarm>(alarmInfo);
            if (string.IsNullOrWhiteSpace(va.url) || va.url.Length <= 0)//缓存里url为空，则只更新url信息
            {
                va.url = status.url;
            }
            else if (string.IsNullOrWhiteSpace(va.alarmTime) && !string.IsNullOrWhiteSpace(sec.alarmTime))//缓存里有数据且报警时间为空，则第一次进入系统的数据为报警证据,再次进入系统的报警时间不为空，则带有报警信息
            {
                sec.url = va.url + ";" + sec.url;//属于更新数据
                va = sec;
            }
            else
            {
                va.url = va.url + ";" + status.url;//属于更新数据
            }
            if ((!string.IsNullOrEmpty(status.latitude) && status.latitude != "0") || (!string.IsNullOrEmpty(status.longitude) && status.longitude != "0") || (!string.IsNullOrEmpty(status.speed) && status.speed != "0"))
            {
                va.latitude = status.latitude; va.longitude = status.longitude; va.speed = status.speed;
            }
            string msg = JsonConvert.SerializeObject(va);
            redisDb3.Set(status.alarmId, msg, new TimeSpan(12, 0, 30));
            redisDb3.Set("alarm" + status.vehicleNo, msg);//车辆报警数据刷新
            Producer(brokerList, "VEHICLE_ALARMAndUrlMsg", msg);//车载设备告警数据
            VehicleAlarmDataToMysql(va, redisDb3, redisDb);
        }
    }
    catch (Exception e)
    {
        Console.WriteLine("设备报警及文件合并信息写入Redis并推送至卡夫卡异常：" + JsonConvert.SerializeObject(status) + JsonConvert.SerializeObject(e));
    }
}
async void VehicleAlarmDataToMysql(VehicleAlarm status, CSRedisClient redisDb3, CSRedisClient redisDb)
{
    try
    {
        string zl = redisDb.Get($@"zl_{status.devGbId}");
        if (!string.IsNullOrWhiteSpace(zl) && (status.platform == "RUIMING" || status.platform == "ZAKJ"))
        {
            return;
        }
        string dtStr = DateTime.Now.ToString("yyyyMMdd");
        if (!string.IsNullOrWhiteSpace(status.url) && status.url.Contains(";"))//证据不为空，且包含多个证据
        {
            string sqlDe = $@"update qskjrecord.B_Vehicle_AlarmAndFile{dtStr} set url='{status.url}' where alarmId='{status.alarmId}' and vehicleNo='{status.vehicleNo}'";
            if ((!string.IsNullOrEmpty(status.latitude) && status.latitude != "0") || (!string.IsNullOrEmpty(status.longitude) && status.longitude != "0") || (!string.IsNullOrEmpty(status.speed) && status.speed != "0"))
            {
                sqlDe = $@"update qskjrecord.B_Vehicle_AlarmAndFile{dtStr} set url='{status.url}',latitude='{status.latitude}',longitude='{status.longitude}',speed='{status.speed}' where alarmId='{status.alarmId}' and vehicleNo='{status.vehicleNo}'";
            }
            MySqlHelper.ExecuteNonQuery(System.Data.CommandType.Text, sqlDe);
        }
        else
        {
            //int[] rlb = { 1 }, r2b = { 2 }, r3b = { 5, 43 }, r4b = { 3 }, r9b = { 39 };//1抽烟_保护5分钟//2打电话//3疲劳驾驶_保护1分钟//4分神,//9超速_保护5分钟
            //int[] rlc = { 89, 6503 }, r2c = { 88, 6502 }, r3c = { 35, 87, 113, 6501 }, r4c = { 90, 6504 }, r9c = { 17, 34, 44, 6573 };//1抽烟_保护5分钟//2打电话//3疲劳驾驶_保护1分钟//4分神//9超速_保护5分钟
            {
                if (status.platform == "ZAKJ")
                {
                    if (status.alarmType == "1")
                    {
                        status.qskjId = 1;//1抽烟
                    }
                    if (status.alarmType == "2")
                    {
                        status.qskjId = 2;//2打电话
                    }
                    if (status.alarmType == "5" || status.alarmType == "43")
                    {
                        status.qskjId = 3;//3疲劳驾驶
                    }
                    if (status.alarmType == "39")
                    {
                        status.qskjId = 9;//9超速
                    }
                }
                if (status.platform == "RUIMING" || status.platform == "zl")
                {
                    if (status.alarmType == "89" || status.alarmType == "6503")
                    {
                        status.qskjId = 1;//1抽烟
                    }
                    if (status.alarmType == "88" || status.alarmType == "6502")
                    {
                        status.qskjId = 2;//2打电话
                    }
                    if (status.alarmType == "35" || status.alarmType == "87" || status.alarmType == "113" || status.alarmType == "6501")
                    {
                        status.qskjId = 3;//3疲劳驾驶
                    }
                    if (status.alarmType == "17" || status.alarmType == "34" || status.alarmType == "44" || status.alarmType == "6573")//241209新增需求屏蔽超速违规过滤
                    {
                        status.qskjId = 9;//9超速
                    }
                }
                if (status.qskjId == 1 || status.qskjId == 3)//|| status.qskjId == 9//241209新增需求屏蔽超速违规过滤
                {
                    string qskj = redisDb3.Get($@"qskj_{status.vehicleNo}{status.qskjId}");//车辆报警类型
                    if (string.IsNullOrEmpty(qskj))
                    {
                        //没有数据，说明是第一条数据，则标记位为不可见状态
                        redisDb3.Set($@"qskj_{status.vehicleNo}{status.qskjId}", 1);
                        status.IsShow = 1;
                        status.IsShowNum = 1;
                    }
                    else
                    {
                        status.IsShowNum = Convert.ToInt32(qskj) + 1;
                        if (qskj == "1")
                        {
                            int t = 0;
                            //第二条数据设为可见状态，并设置1分钟保护期
                            if (status.qskjId == 3)
                            {
                                //疲劳驾驶保护时间1分钟
                                t = 1;
                            }
                            if (status.qskjId == 1)//|| status.qskjId == 9//241209新增需求屏蔽超速违规过滤
                            {
                                //1抽烟9超速保护时间5分钟
                                t = 5;
                            }
                            redisDb3.Set($@"qskj_{status.vehicleNo}{status.qskjId}", status.IsShowNum, new TimeSpan(0, t, 0));
                            status.IsShow = 0;
                        }
                        else
                        {
                            //不为空且不是第二条数据则在保护期内，也设为不可见状态
                            status.IsShow = 1;
                        }
                    }
                }
            }
            if (DateTime.Now.Hour <= 7)
            {
                string exists = $@"SELECT TABLE_NAME FROM information_schema.TABLES WHERE TABLE_SCHEMA = 'qskjrecord' AND TABLE_NAME = 'B_Vehicle_AlarmAndFile{dtStr}';";
                object resExi = MySqlHelper.ExecuteScalar(CommandType.Text, exists);
                if (resExi == null || resExi == DBNull.Value)
                {
                    string sqlCt = $@"create table IF NOT EXISTS qskjrecord.B_Vehicle_AlarmAndFile{dtStr}
                        (
                           id                   bigint not null auto_increment,
                           devGbId              varchar(50) comment '设备国标id',
                           alarmId              varchar(50) comment '报警id',
                           vehicleNo            varchar(50) comment '车牌号',
                           alarmMainType        int comment '1主动安全DSM报警2主动安全ADAS报警3行业监管报警4设备报警',
                           alarmSubType         int comment '1.1抽烟1.2接打电话1.3疲劳驾驶1.4分神1.5驾驶员异常1.6摄像头遮挡1.7红外阻隔型墨镜报警2.1前向碰撞预警2.2车道偏离2.3车距过近3.1超速3.2连续行驶疲劳驾驶3.3两到五点运营4.1GNSS模块发生故障4.2GNSS天线未接或被剪断4.3GNSS天线短路4.4终端主电源欠压4.5终端主电源掉电4.6摄像头故障',
                           alarmType            varchar(50) comment '1.1抽烟1.2接打电话1.3疲劳驾驶1.4分神1.5驾驶员异常1.6摄像头遮挡1.7红外阻隔型墨镜报警2.1前向碰撞预警2.2车道偏离2.3车距过近3.1超速3.2连续行驶疲劳驾驶3.3两到五点运营4.1GNSS模块发生故障4.2GNSS天线未接或被剪断4.3GNSS天线短路4.4终端主电源欠压4.5终端主电源掉电4.6摄像头故障',
                           alarmTime            datetime comment '告警时间yyyy-MM-dd HH:mm:ss',
                           latitude             varchar(50) comment '经度 （必填）格式ddd.ddddddddd (默认WGS84坐标)',
                           longitude            varchar(50) comment '纬度（必填）格式
                                     ddd.ddddddddd (默认WGS84坐标)',
                           speed                decimal(18,2) comment '速度（非必填） 速度（Km/s）',
                           url                  text comment '报警附件',
                           platform             varchar(50) comment '车载平台厂商1中安2锐明3海康',
                           timestamp            bigint comment '上报时间戳',
                           createtime           datetime,
                           IsInpector           int default 0,
                           IsShow               int default 0,
                           IsShowNum            int default 0,
                           primary key (id),
                           INDEX index_alarmId (alarmId),
                           INDEX index_vehicleNo (vehicleNo),
                           INDEX index_createtime (createtime),
                           INDEX index_IsInpector (IsInpector),
                           INDEX index_IsShow (IsShow)
                        );";
                    MySqlHelper.ExecuteNonQuery(System.Data.CommandType.Text, sqlCt);
                }
            }
            string sql = $@"insert into qskjrecord.B_Vehicle_AlarmAndFile{dtStr}(devGbId,alarmId,vehicleNo,alarmMainType,alarmSubType,alarmType,alarmTime,latitude,longitude,speed,url,platform,timestamp,createtime,IsInpector,IsShow,IsShowNum)
                        values('{status.devGbId}','{status.alarmId}','{status.vehicleNo}',{status.alarmMainType},{status.alarmSubType},'{status.alarmType}','{status.alarmTime}','{status.latitude}','{status.longitude}',{status.speed},'{status.url}','{status.platform}',{status.timestamp},'{DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")}',{status.IsInpector},{status.IsShow},{status.IsShowNum})";
            //Console.WriteLine(sql);
            int res = MySqlHelper.ExecuteNonQuery(System.Data.CommandType.Text, sql);
            if (status.IsShow == 0)
            {
                string sqlIsShow = $@"insert into qskjrecord.D_VehicleAlarmShowDetaile(vehicleNo,alarmId,alarmType,qskjId,alarmTime,datetime)values('{status.vehicleNo}','{status.alarmId}','{status.alarmType}',{status.qskjId},'{status.alarmTime}',now())";
                MySqlHelper.ExecuteNonQuery(System.Data.CommandType.Text, sqlIsShow);
            }
        }
    }
    catch (Exception e)
    {
        Console.WriteLine(JsonConvert.SerializeObject(status));
        Console.WriteLine("设备报警信息文件信息写入数据库异常" + JsonConvert.SerializeObject(e));
    }
}